package com.px.user.exception;

import com.px.common.core.RespCode;
import com.px.common.core.RespException;
import com.px.common.core.Response;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.validation.ConstraintViolationException;
import java.util.LinkedHashMap;
import java.util.Map;

@ControllerAdvice
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(
            MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Map<String, Object> data = new LinkedHashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(f -> data.put(f.getField(), f.getDefaultMessage()));
        return new ResponseEntity<>(Response.fail(RespCode.PARA_ERROR, data), headers, status);
    }

    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Map<String, Object> data = new LinkedHashMap<String, Object>() {{
            put("data", ex.getMessage());
        }};
        return new ResponseEntity<>(Response.fail(RespCode.PARA_ERROR, data), headers, status);
    }

    @Override
    protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Map<String, Object> data = new LinkedHashMap<String, Object>() {{
            put(ex.getVariableName(), ex.getMessage());
        }};
        return new ResponseEntity<>(Response.fail(RespCode.PARA_ERROR, data), headers, status);
    }

    @Override
    protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Map<String, Object> data = new LinkedHashMap<String, Object>() {{
            put(ex.getParameterName(), ex.getMessage());
        }};
        return new ResponseEntity<>(Response.fail(RespCode.PARA_ERROR, data), headers, status);
    }

    @ResponseBody
    @ExceptionHandler(value = RespException.class)
    public Response RespExceptionHandler(RespException e) {
        return Response.fail(e);
    }

    @ResponseBody
    @ExceptionHandler(value = DuplicateKeyException.class)
    public Response DuplicateKeyExceptionHandler(DuplicateKeyException e) {
        return Response.fail(e);
    }

    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public Response ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        return Response.fail(e);
    }
}
